/*
 * OperatorVertex.java
 *
 * Created on August 23, 2007, 1:53 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package dnbW.queryW.visualW;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 *
 * @author zhouyong
 */
public class OperatorVertex extends PredicateVertex {

    public static final String AND_OP = "and";
    public static final String OR_OP = "or";
    public static final String EQ_OP = "=";
    private String _operator;

    /** Creates a new instance of OperatorVertex */
    public OperatorVertex(String operator) {
        setOperator(operator);
        _selfExpression = getOperator();
    }

    public String getOperator() {
        return _operator;
    }

    public void setOperator(String operator) {
        this._operator = operator;
        _selfExpression = _operator;
    }

    public List<List<PredicateVertex>> getPredicateList() {

        List<List<PredicateVertex>> list = 
                    new ArrayList<List<PredicateVertex>>();
        
        if(OR_OP.equals(this.getOperator())){
            
            for(Enumeration em = this.children(); em.hasMoreElements();){
                PredicateVertex pv = (PredicateVertex) em.nextElement();
                list.addAll(pv.getPredicateList());
            }
        }
        else if(AND_OP.equals(this.getOperator())){
            
            for(Enumeration em = this.children(); em.hasMoreElements();){
                PredicateVertex pv = (PredicateVertex) em.nextElement();
                
                if(list.size() == 0){
                    for(List<PredicateVertex> l : pv.getPredicateList()){
                        List<PredicateVertex> ldup = new ArrayList<PredicateVertex>();
                        ldup.addAll(l);
                        list.add(ldup);
                    }
                }
                else{
                    int oldListSize = list.size();
                    List<List<PredicateVertex>> toBeRemoved = 
                            new ArrayList<List<PredicateVertex>>();
                    
                    for(int i=0; i<oldListSize; i++){
                        List<PredicateVertex> l = list.get(i);
                        toBeRemoved.add(l);
                        
                        for(List<PredicateVertex> lsub : pv.getPredicateList()){
                            List<PredicateVertex> lreplace = 
                                    new ArrayList<PredicateVertex>();
                            lreplace.addAll(l);
                            lreplace.addAll(lsub);
                            list.add(lreplace);
                        }
                    }
                    
                    list.removeAll(toBeRemoved);
                }
            }
        }else{
            
            // handle the join vertex
            List<PredicateVertex> l1 = new ArrayList<PredicateVertex>();
            l1.add(this);
            
            list.add(l1);
        }
        
        return list;
    }
    
    public String toString(){
        return this.getOperator();
    }

    @Override
    public Map<Integer, Long> getIdentityPathMapFinal() {
        Map<Integer, Long> result = new TreeMap<Integer, Long>();
        
        if(this.getOperator().equalsIgnoreCase("and")){
            for (Enumeration em = this.children(); em.hasMoreElements();) {
                PredicateVertex next = (PredicateVertex) em.nextElement();
                if(result.isEmpty())
                    result.putAll(next.getIdentityPathMapFinal());
                else
                    result.entrySet().retainAll(next.getIdentityPathMapFinal().entrySet());
            }
        } else {
            for (Enumeration em = this.children(); em.hasMoreElements();) {
                PredicateVertex next = (PredicateVertex) em.nextElement();
                result.putAll(next.getIdentityPathMapFinal());
            }
        }
        return result;
    }
    
    public static String getOperatorKey(String op) {
        if (">".equals(op)) {
            return "Operator.GT";
        } else if (">=".equals(op)) {
            return "Operator.GTE";
        } else if ("<".equals(op)) {
            return "Operator.LT";
        } else if ("<=".equals(op)) {
            return "Operator.LTE";
        } else if ("=".equals(op)) {
            return "Operator.EQ";
        } else if ("!=".equals(op)) {
            return "Operator.NE";
        } else if ("Like".equalsIgnoreCase(op)) {
            return "Operator.LK";
        } else if("and".equalsIgnoreCase(op)){
            return "Operator.AND";
        }else if("or".equalsIgnoreCase(op)){
            return "Operator.OR";
        }else{
            return "";
        }
    }
    
}